package org.linloong.config.monitor;

import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.linloong.modules.apis.monitor.service.MonitorRemoteService;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.http.client.reactive.ReactorClientHttpConnector;
import org.springframework.web.reactive.function.client.ClientRequest;
import org.springframework.web.reactive.function.client.ExchangeFilterFunction;
import org.springframework.web.reactive.function.client.WebClient;
import org.springframework.web.reactive.function.client.support.WebClientAdapter;
import org.springframework.web.service.invoker.HttpServiceProxyFactory;
import reactor.core.publisher.Mono;
import reactor.netty.http.client.HttpClient;

import java.time.Duration;

@Configuration
@RequiredArgsConstructor
@Slf4j
public class MonitorWebClientConfig {
    private final TokenManager tokenManager;

    /**
     * 带 Token 的 WebClient（适配文档所有业务接口，修复 ClientRequest.mutate() 不存在问题）
     */
    @Bean
    public WebClient monitorWebClient() {
        // 配置 HTTP 超时（文档接口请求超时控制）
        HttpClient httpClient = HttpClient.create()
                .responseTimeout(Duration.ofSeconds(30)) // 响应超时30s（匹配文档大数据量查询场景）
                .doOnConnected(conn -> conn
                        .addHandlerLast(new io.netty.handler.timeout.ReadTimeoutHandler(30))
                        .addHandlerLast(new io.netty.handler.timeout.WriteTimeoutHandler(30)));

        // 定义 Token 过滤器：通过 ClientRequest.from() 重建请求，避免使用 mutate()
        ExchangeFilterFunction tokenFilter = ExchangeFilterFunction.ofRequestProcessor(clientRequest -> {
            try {
                // 1. 获取有效 Token（遵循文档"数据令牌请求"章节逻辑）
                String validToken = tokenManager.getValidToken();
                // 2. 重建请求并添加 Authorization 头（文档要求：Bearer + 空格 + Token）
                ClientRequest newRequest = ClientRequest.from(clientRequest)
                        .header(HttpHeaders.AUTHORIZATION, "Bearer " + validToken)
                        .build();
                log.debug("请求添加认证头: {} {}", clientRequest.method(), clientRequest.url());
                return Mono.just(newRequest);
            } catch (Exception e) {
                log.error("添加认证头失败: ", e);
                return Mono.just(clientRequest); // 即使失败也继续请求，方便调试
            }
        });

        return WebClient.builder()
                .baseUrl("https://sso.cnecop.cn") // 文档中所有接口统一前缀
                .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE)
                .filter(tokenFilter) // 注入 Token 过滤器
                .clientConnector(new ReactorClientHttpConnector(httpClient))
                .build();
    }

    @Bean("monitorRemoteService")
    public MonitorRemoteService monitorRemoteApi(WebClient webClient) {
        HttpServiceProxyFactory factory = HttpServiceProxyFactory
                .builderFor(WebClientAdapter.create(webClient))
                .build();
        return factory.createClient(MonitorRemoteService.class);
    }

}